/*
 * Copyright (c) 2018-2023 北京华恒盛世科技有限公司
 * QUICKPOOL is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
*/

#ifndef LIST_H
#define LIST_H

#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#define LIST_NUM_ENTS(L) ((L) == NULL ? 0 : (L)->numElements)

typedef struct list {
    struct list *forw;          /* Pointer of forward element. */
    struct list *back;          /* Pointer of backward element. */
    uint32_t     numElements;   /* Number of elements in the list. */
    char        *name;          /* Name of the list. */
} LIST_T;

typedef struct list_iterator {
    char       *name;
    LIST_T     *list;
    LIST_T     *curentry;
} LIST_ITERATOR_T;

typedef struct list_proxy {
    LIST_T *forw;
    LIST_T *back;
    void *subject;
} LIST_PROXY_T;

typedef void          (*LIST_DESTROY_FUNC_T)(LIST_T *);

/* Declare functions for list handling. */
extern LIST_T *gf_list_make(const char *);
extern void gf_list_free(LIST_T *, void (*func)(void *));
extern void gf_free_none(void *);
extern void gf_free_proxy_string(void *);
extern int gf_list_insert(LIST_T *, LIST_T *, LIST_T *);
extern int gf_list_insert_sort(LIST_T *, LIST_T *, int (*cmp)(const void *, const void *));
extern LIST_T *gf_list_remove(LIST_T *, LIST_T *);
extern LIST_T *gf_list_pop(LIST_T *);
extern LIST_T *gf_list_duplicate(LIST_T *, int);

extern LIST_T *gf_list_search(LIST_T *, void *, int (*equal)(void *, void *));
extern int gf_listiterator_link(LIST_ITERATOR_T *, LIST_T *);
extern LIST_T *gf_listiterator_curentry(LIST_ITERATOR_T *);
extern void gf_listiterator_getnext(LIST_ITERATOR_T *, LIST_T **);
extern void gf_listiterator_getprev(LIST_ITERATOR_T *, LIST_T **);
extern int gf_listiterator_isend(LIST_ITERATOR_T *);

#endif /* LIST_H */
